#ifndef MOONLIGHT_OHOS_SYNCHRONIZED_H
#define MOONLIGHT_OHOS_SYNCHRONIZED_H

#include <mutex>

template<class T, class... Args>
class Synchronized {
public:
    static Synchronized<T, Args...> make(Args&&... args) { return Synchronized<T>(args...); }
    struct LeasePack {
        std::unique_lock<std::mutex> lock;
        T& obj;
    };
    LeasePack operator*() { return { .lock = std::unique_lock(mtx), .obj = *obj }; }

private:
    Synchronized(Args&&... args) : obj(std::make_unique<T>(std::forward<Args>(args)...)) {}
    Synchronized(const Synchronized<T> &) = delete;
    Synchronized<T> &operator=(const Synchronized<T> &) = delete;

    std::mutex mtx;
    std::unique_ptr<T> obj;
};

#endif //MOONLIGHT_OHOS_SYNCHRONIZED_H
